<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
<meta name="viewport" content="width=device-width">
<meta name="theme-color" content="#222"><meta name="generator" content="Hexo 5.4.0">


  <link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png">
  <link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png">
  <link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png">
  <link rel="mask-icon" href="/images/logo.svg" color="#222">

<link rel="stylesheet" href="/css/main.css">



<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.2.0/css/all.min.css" integrity="sha256-AbA177XfpSnFEvgpYu1jMygiLabzPCJCRIBtR5jGc0k=" crossorigin="anonymous">
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.1.1/animate.min.css" integrity="sha256-PR7ttpcvz8qrF57fur/yAx1qXMFJeJFiA6pSzWi0OIE=" crossorigin="anonymous">

<script class="next-config" data-name="main" type="application/json">{"hostname":"tomstand.gitee.io","root":"/","images":"/images","scheme":"Muse","darkmode":false,"version":"8.13.0","exturl":false,"sidebar":{"position":"left","display":"post","padding":18,"offset":12},"copycode":{"enable":false,"style":null},"bookmark":{"enable":false,"color":"#222","save":"auto"},"mediumzoom":false,"lazyload":false,"pangu":false,"comments":{"style":"tabs","active":null,"storage":true,"lazyload":false,"nav":null},"stickytabs":false,"motion":{"enable":true,"async":false,"transition":{"post_block":"fadeIn","post_header":"fadeInDown","post_body":"fadeInDown","coll_header":"fadeInLeft","sidebar":"fadeInUp"}},"prism":false,"i18n":{"placeholder":"Searching...","empty":"We didn't find any results for the search: ${query}","hits_time":"${hits} results found in ${time} ms","hits":"${hits} results found"}}</script><script src="/js/config.js"></script>

    <meta name="description" content="分布式搜索和分析引擎-Elasticsearch Elasticsearch 是一个分布式的免费开源搜索和分析引擎，适用于包括文本、数字、地理空间、结构化和非结构化数据等在内的所有类型的数据。Elasticsearch 在Apache Lucene 的基础上开发而成，由 Elasticsearch N.V.（即现在的Elastic）于 2010 年首次发布。Elasticsearch 以其简单的">
<meta property="og:type" content="article">
<meta property="og:title" content="猿日记">
<meta property="og:url" content="https://tomstand.gitee.io/2023/11/21/%E5%88%86%E5%B8%83%E5%BC%8F%E6%90%9C%E7%B4%A2%E5%92%8C%E5%88%86%E6%9E%90%E5%BC%95%E6%93%8E-Elasticsearch/index.html">
<meta property="og:site_name" content="猿日记">
<meta property="og:description" content="分布式搜索和分析引擎-Elasticsearch Elasticsearch 是一个分布式的免费开源搜索和分析引擎，适用于包括文本、数字、地理空间、结构化和非结构化数据等在内的所有类型的数据。Elasticsearch 在Apache Lucene 的基础上开发而成，由 Elasticsearch N.V.（即现在的Elastic）于 2010 年首次发布。Elasticsearch 以其简单的">
<meta property="og:locale" content="en_US">
<meta property="og:image" content="https://img-blog.csdnimg.cn/img_convert/7351e5fc39fb918015ac346e79909768.png">
<meta property="og:image" content="https://img-blog.csdnimg.cn/img_convert/5d0e8493f39d5d53de750086c9ea2867.png">
<meta property="article:published_time" content="2023-11-21T12:16:19.931Z">
<meta property="article:modified_time" content="2023-11-21T12:16:19.931Z">
<meta property="article:author" content="tomstand">
<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="https://img-blog.csdnimg.cn/img_convert/7351e5fc39fb918015ac346e79909768.png">


<link rel="canonical" href="https://tomstand.gitee.io/2023/11/21/%E5%88%86%E5%B8%83%E5%BC%8F%E6%90%9C%E7%B4%A2%E5%92%8C%E5%88%86%E6%9E%90%E5%BC%95%E6%93%8E-Elasticsearch/">



<script class="next-config" data-name="page" type="application/json">{"sidebar":"","isHome":false,"isPost":true,"lang":"en","comments":true,"permalink":"https://tomstand.gitee.io/2023/11/21/%E5%88%86%E5%B8%83%E5%BC%8F%E6%90%9C%E7%B4%A2%E5%92%8C%E5%88%86%E6%9E%90%E5%BC%95%E6%93%8E-Elasticsearch/","path":"2023/11/21/分布式搜索和分析引擎-Elasticsearch/","title":""}</script>

<script class="next-config" data-name="calendar" type="application/json">""</script>
<title> | 猿日记</title>
  






  <noscript>
    <link rel="stylesheet" href="/css/noscript.css">
  </noscript>
</head>

<body itemscope itemtype="http://schema.org/WebPage" class="use-motion">
  <div class="headband"></div>

  <main class="main">
    <header class="header" itemscope itemtype="http://schema.org/WPHeader">
      <div class="header-inner"><div class="site-brand-container">
  <div class="site-nav-toggle">
    <div class="toggle" aria-label="Toggle navigation bar" role="button">
    </div>
  </div>

  <div class="site-meta">

    <a href="/" class="brand" rel="start">
      <i class="logo-line"></i>
      <p class="site-title">猿日记</p>
      <i class="logo-line"></i>
    </a>
  </div>

  <div class="site-nav-right">
    <div class="toggle popup-trigger">
    </div>
  </div>
</div>







</div>
        
  
  <div class="toggle sidebar-toggle" role="button">
    <span class="toggle-line"></span>
    <span class="toggle-line"></span>
    <span class="toggle-line"></span>
  </div>

  <aside class="sidebar">

    <div class="sidebar-inner sidebar-nav-active sidebar-toc-active">
      <ul class="sidebar-nav">
        <li class="sidebar-nav-toc">
          Table of Contents
        </li>
        <li class="sidebar-nav-overview">
          Overview
        </li>
      </ul>

      <div class="sidebar-panel-container">
        <!--noindex-->
        <div class="post-toc-wrap sidebar-panel">
            <div class="post-toc animated"><ol class="nav"><li class="nav-item nav-level-1"><a class="nav-link" href="#%E5%88%86%E5%B8%83%E5%BC%8F%E6%90%9C%E7%B4%A2%E5%92%8C%E5%88%86%E6%9E%90%E5%BC%95%E6%93%8E-Elasticsearch"><span class="nav-number">1.</span> <span class="nav-text">分布式搜索和分析引擎-Elasticsearch</span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#%E5%BA%94%E7%94%A8%E5%9C%BA%E6%99%AF"><span class="nav-number">1.1.</span> <span class="nav-text">应用场景</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E7%B4%A2%E5%BC%95%E5%92%8C%E6%96%87%E6%A1%A3%E8%83%BD%E6%90%9C%E7%B4%A2%E5%88%B0%E7%9A%84%E5%9C%BA%E6%99%AF"><span class="nav-number">1.2.</span> <span class="nav-text">索引和文档能搜索到的场景</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E5%80%92%E6%8E%92%E7%B4%A2%E5%BC%95%E7%9A%84%E5%8E%9F%E7%90%86"><span class="nav-number">1.3.</span> <span class="nav-text">倒排索引的原理</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#Elasticsearch%E8%AF%BB%E6%95%B0%E6%8D%AE%E8%BF%87%E7%A8%8B"><span class="nav-number">1.4.</span> <span class="nav-text">Elasticsearch读数据过程</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#Elasticsearch-%E6%90%9C%E7%B4%A2%E6%95%B0%E6%8D%AE%E8%BF%87%E7%A8%8B"><span class="nav-number">1.5.</span> <span class="nav-text">Elasticsearch 搜索数据过程</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E5%86%99%E6%95%B0%E6%8D%AE%E5%BA%95%E5%B1%82%E5%8E%9F%E7%90%86"><span class="nav-number">1.6.</span> <span class="nav-text">写数据底层原理</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#Elasticsearch-%E5%9C%A8%E9%83%A8%E7%BD%B2%E6%97%B6%EF%BC%8C%E5%AF%B9-Linux-%E7%9A%84%E8%AE%BE%E7%BD%AE%E6%9C%89%E5%93%AA%E4%BA%9B%E4%BC%98%E5%8C%96%E6%96%B9%E6%B3%95%EF%BC%9F"><span class="nav-number">1.7.</span> <span class="nav-text">Elasticsearch 在部署时，对 Linux 的设置有哪些优化方法？</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E5%9C%A8%E5%B9%B6%E5%8F%91%E6%83%85%E5%86%B5%E4%B8%8B%EF%BC%8CElasticsearch-%E5%A6%82%E6%9E%9C%E4%BF%9D%E8%AF%81%E8%AF%BB%E5%86%99%E4%B8%80%E8%87%B4"><span class="nav-number">1.8.</span> <span class="nav-text">在并发情况下，Elasticsearch 如果保证读写一致</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#%E4%BB%8E%E5%8A%A8%E6%80%81%E7%B4%A2%E5%BC%95%E4%B8%8A%E4%BC%98%E5%8C%96"><span class="nav-number">1.8.1.</span> <span class="nav-text">从动态索引上优化</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#%E4%BB%8E%E5%AD%98%E5%82%A8%E5%B1%82%E9%9D%A2%E4%BC%98%E5%8C%96"><span class="nav-number">1.8.2.</span> <span class="nav-text">从存储层面优化</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#%E4%BB%8E%E9%83%A8%E7%BD%B2%E5%B1%82%E9%9D%A2%E4%BC%98%E5%8C%96"><span class="nav-number">1.8.3.</span> <span class="nav-text">从部署层面优化</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#Elasticsearch-%E9%9B%86%E7%BE%A4%E9%85%8D%E7%BD%AE"><span class="nav-number">1.9.</span> <span class="nav-text">Elasticsearch 集群配置</span></a></li></ol></li></ol></div>
        </div>
        <!--/noindex-->

        <div class="site-overview-wrap sidebar-panel">
          <div class="site-author site-overview-item animated" itemprop="author" itemscope itemtype="http://schema.org/Person">
  <p class="site-author-name" itemprop="name">tomstand</p>
  <div class="site-description" itemprop="description"></div>
</div>
<div class="site-state-wrap site-overview-item animated">
  <nav class="site-state">
      <div class="site-state-item site-state-posts">
        <a href="/archives/">
          <span class="site-state-item-count">12</span>
          <span class="site-state-item-name">posts</span>
        </a>
      </div>
  </nav>
</div>



        </div>
      </div>
    </div>
  </aside>
  <div class="sidebar-dimmer"></div>


    </header>

    
  <div class="back-to-top" role="button" aria-label="Back to top">
    <i class="fa fa-arrow-up"></i>
    <span>0%</span>
  </div>

<noscript>
  <div class="noscript-warning">Theme NexT works best with JavaScript enabled</div>
</noscript>


    <div class="main-inner post posts-expand">


  


<div class="post-block">
  
  

  <article itemscope itemtype="http://schema.org/Article" class="post-content" lang="en">
    <link itemprop="mainEntityOfPage" href="https://tomstand.gitee.io/2023/11/21/%E5%88%86%E5%B8%83%E5%BC%8F%E6%90%9C%E7%B4%A2%E5%92%8C%E5%88%86%E6%9E%90%E5%BC%95%E6%93%8E-Elasticsearch/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/avatar.gif">
      <meta itemprop="name" content="tomstand">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="猿日记">
      <meta itemprop="description" content="">
    </span>

    <span hidden itemprop="post" itemscope itemtype="http://schema.org/CreativeWork">
      <meta itemprop="name" content=" | 猿日记">
      <meta itemprop="description" content="">
    </span>
      <header class="post-header">
        <h1 class="post-title" itemprop="name headline">
          
        </h1>

        <div class="post-meta-container">
          <div class="post-meta">
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-calendar"></i>
      </span>
      <span class="post-meta-item-text">Posted on</span>

      <time title="Created: 2023-11-21 20:16:19" itemprop="dateCreated datePublished" datetime="2023-11-21T20:16:19+08:00">2023-11-21</time>
    </span>

  
</div>

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">
        <h1 id="分布式搜索和分析引擎-Elasticsearch"><a href="#分布式搜索和分析引擎-Elasticsearch" class="headerlink" title="分布式搜索和分析引擎-Elasticsearch"></a>分布式搜索和分析引擎-Elasticsearch</h1><blockquote>
<p><strong>Elasticsearch</strong> 是一个分布式的免费开源搜索和分析引擎，适用于包括文本、数字、地理空间、结构化和非结构化数据等在内的所有类型的数据。Elasticsearch 在Apache Lucene 的基础上开发而成，由 Elasticsearch N.V.（即现在的Elastic）于 2010 年首次发布。Elasticsearch 以其简单的 REST 风格 API、分布式特性、速度和可扩展性而闻名，是Elastic Stack 的核心组件；Elastic Stack 是一套适用于数据采集、扩充、存储、分析和可视化的免费开源工具。</p>
</blockquote>
<h2 id="应用场景"><a href="#应用场景" class="headerlink" title="应用场景"></a>应用场景</h2><ul>
<li>将搜索框添加到应用或网站</li>
<li>存储和分析日志，指标和安全事件数据</li>
<li>使用机器学习自动实时建模数据行为</li>
<li>使用Elasticsearch作为存储引擎自动化业务工作流程</li>
<li>使用Elasticsearch作为地理信息系统（GIS）管理，集成和分析空间信息</li>
<li>使用Elasticsearch作为生物信息学研究工具来存储和处理遗传数据</li>
</ul>
<h2 id="索引和文档能搜索到的场景"><a href="#索引和文档能搜索到的场景" class="headerlink" title="索引和文档能搜索到的场景"></a>索引和文档能搜索到的场景</h2><ul>
<li>区分全文字符串字段和精确值字符串字段</li>
<li>执行特定于语言的文本分析</li>
<li>优化字段以进行部分匹配</li>
<li>使用自定义日期格式</li>
<li>使用无法自动检测到的数据类型，例geo_point和geo_shape</li>
</ul>
<h2 id="倒排索引的原理"><a href="#倒排索引的原理" class="headerlink" title="倒排索引的原理"></a>倒排索引的原理</h2><blockquote>
<p>传统的索引机制是通过文章，逐个遍历找到对应关键词的位置</p>
<p><strong>倒排索引</strong>  是通过分词策略，形成了词和文章的映射关系表，这种词典+映射表就是倒排索引</p>
<p>有了倒排索引，就能实现 o（1）时间复杂度的效率检索文章了，极大的提高了</p>
<p>检索效率</p>
</blockquote>
<p><img src="https://img-blog.csdnimg.cn/img_convert/7351e5fc39fb918015ac346e79909768.png" alt="image-20210323160252906"></p>
<p>倒排索引的底层实现是基于：<strong>FST（Finite State Transducer）数据结构</strong>。</p>
<p>lucene 从 4+版本后开始大量使用的数据结构是 FST。FST 有两个优点：</p>
<p>1、空间占用小。通过对词典中单词前缀和后缀的重复利用，压缩了存储空间；</p>
<p>2、查询速度快。O(len(str))的查询时间复杂度。</p>
<p><strong>FSM(Finite State Machines) 有限状态机</strong>: 表示有限个状态（State）集合以及这些状态之间转移和动作的数学模型。其中一个状态被标记为开始状态，0个或更多的状态被标记为final状态。<br>一个FSM同一时间只处于1个状态。FSM很通用，可以用来表示多种处理过程，下面的FSM描述了《小猫咪的一天》。</p>
<p><img src="https://img-blog.csdnimg.cn/img_convert/5d0e8493f39d5d53de750086c9ea2867.png" alt="image-20210323161913885"></p>
<p>其中“睡觉”或者“吃饭”代表的是状态,而“提供食物”或者“东西移动”则代表了转移。图中这个FSM是对小猫活动的一个抽象（这里并没有刻意写开始状态或者final状态），小猫咪不能同时的即处于“玩耍”又处于“睡觉”状态，并且从一个状态到下一个状态的转换只有一个输入。“睡觉”状态并不知道是从什么状态转换过来的，可能是“玩耍”，也可能是”猫砂窝”。</p>
<p>如果《小猫咪的一天》这个FSM接收以下的输入:</p>
<p>提供食物<br>有大声音<br>安静<br>消化食物<br>那么我们会明确的知道，小猫咪会这样依次变化状态： 睡觉-&gt;吃饭-&gt;躲藏-&gt;吃饭-&gt;猫砂窝.</p>
<p><strong>FST</strong>，不但能共享前缀还能共享后缀。不但能判断查找的key是否存在，还能给出响应的输入output。 它在时间复杂度和空间复杂度上都做了最大程度的优化，使得Lucene能够将Term Dictionary完全加载到内存，快速的定位Term找到响应的output（posting倒排列表）。</p>
<h2 id="Elasticsearch读数据过程"><a href="#Elasticsearch读数据过程" class="headerlink" title="Elasticsearch读数据过程"></a>Elasticsearch读数据过程</h2><p>可以通过 doc id 来查询，会根据 doc id 进行 hash，判断出来当时把 doc id 分配到了哪个 shard 上面去，从那个 shard 去查询。</p>
<ul>
<li>客户端发送请求到任意一个 node，成为 coordinate node 。</li>
<li>coordinate node 对 doc id 进行哈希路由，将请求转发到对应的 node，此时会使用 round-robin <strong>随机轮询</strong><br><strong>算法</strong>，在 primary shard 以及其所有 replica 中随机选择一个，让读请求负载均衡。</li>
<li>接收请求的 node 返回 document 给 coordinate node 。</li>
<li>coordinate node 返回 document 给客户端。</li>
</ul>
<h2 id="Elasticsearch-搜索数据过程"><a href="#Elasticsearch-搜索数据过程" class="headerlink" title="Elasticsearch 搜索数据过程"></a>Elasticsearch 搜索数据过程</h2><p>es 最强大的是做全文检索，就是比如你有三条数据：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">java真好玩儿啊</span><br><span class="line">java好难学啊</span><br><span class="line">j2ee特别牛</span><br></pre></td></tr></table></figure>

<p>你根据 java 关键词来搜索，将包含 java 的 document 给搜索出来。es 就会给你返回：java 真好玩儿啊，java 好难学啊。</p>
<ul>
<li>客户端发送请求到一个 coordinate node 。</li>
<li>协调节点将搜索请求转发到所有的 shard 对应的 primary shard 或 replica shard ，都可以。</li>
<li>query phase：每个 shard 将自己的搜索结果（其实就是一些 doc id ）返回给协调节点，由协调节点进行数据的合并、排序、分页等操作，产出最终结果。</li>
<li>fetch phase：接着由协调节点根据 doc id 去各个节点上拉取实际的 document 数据，最终返回给客户端。</li>
</ul>
<blockquote>
<p>写请求是写入 primary shard，然后同步给所有的 replica shard；读请求可以从 primary shard 或 replica shard 读取，采用的是随机轮询算法。</p>
</blockquote>
<h2 id="写数据底层原理"><a href="#写数据底层原理" class="headerlink" title="写数据底层原理"></a>写数据底层原理</h2><ul>
<li>先写入内存 buffer，在 buffer 里的时候数据是搜索不到的；同时将数据写入 translog 日志文件。</li>
</ul>
<ul>
<li>如果 buffer 快满了，或者到一定时间，就会将内存 buffer 数据 refresh 到一个新的 segment file 中，但是此时数据不是直接进入 segment file 磁盘文件，而是先进入 os cache 。这个过程就是 refresh 。</li>
</ul>
<ul>
<li>每隔 1 秒钟，es 将 buffer 中的数据写入一个新的 segment file ，每秒钟会产生一个新的磁盘文件 segment file ，这个 segment file 中就存储最近 1 秒内 buffer 中写入的数据。</li>
</ul>
<ul>
<li>但是如果 buffer 里面此时没有数据，那当然不会执行 refresh 操作，如果 buffer 里面有数据，默认 1 秒钟执行一次 refresh 操作，刷入一个新的 segment file 中。</li>
</ul>
<ul>
<li>操作系统里面，磁盘文件其实都有一个东西，叫做 os cache ，即操作系统缓存，就是说数据写入磁盘文件之前，会先进入 os cache ，先进入操作系统级别的一个内存缓存中去。只要 buffer 中的数据被 refresh 操作刷入 os cache 中，这个数据就可以被搜索到了。</li>
</ul>
<ul>
<li>为什么叫 es 是准实时的？ NRT ，全称 near real-time 。默认是每隔 1 秒 refresh 一次的，所以 es 是准实时的，因为写入的数据 1 秒之后才能被看到。可以通过 es 的 restful api 或者 java api ，手动执行一次 refresh 操作，就是手动将 buffer 中的数据刷入 os cache 中，让数据立马就可以被搜索到。只要数据被输入 os cache 中，buffer 就会被清空了，因为不需要保留 buffer 了，数据在 translog 里面已经持久化到磁盘去一份了。</li>
</ul>
<ul>
<li>重复上面的步骤，新的数据不断进入 buffer 和 translog，不断将 buffer 数据写入一个又一个新的 segment file 中去，每次 refresh 完 buffer 清空，translog 保留。随着这个过程推进，translog 会变得越来越大。当 translog 达到一定长度的时候，就会触发 commit 操作。</li>
</ul>
<ul>
<li>commit 操作发生第一步，就是将 buffer 中现有数据 refresh 到 os cache 中去，清空 buffer。然后，将一个 commit point 写入磁盘文件，里面标识着这个 commit point 对应的所有 segment file ，同时强行将 os cache 中目前所有的数据都 fsync 到磁盘文件中去。最后清空 现有 translog 日志文件，重启一个 translog，此时 commit 操作完成。</li>
</ul>
<ul>
<li>这个 commit 操作叫做 flush 。默认 30 分钟自动执行一次 flush ，但如果 translog 过大，也会触发 flush 。flush 操作就对应着 commit 的全过程，我们可以通过 es api，手动执行 flush 操作，手动将 os cache 中的数据 fsync 强刷到磁盘上去。</li>
</ul>
<ul>
<li>translog 日志文件的作用是什么？你执行 commit 操作之前，数据要么是停留在 buffer 中，要么是停留在 os cache 中，无论是 buffer 还是 os cache 都是内存，一旦这台机器死了，内存中的数据就全丢了。所以需要将数据对应的操作写入一个专门的日志文件 translog 中，一旦此时机器宕机，再次重启的时候，es 会自动读取 translog 日志文件中的数据，恢复到内存 buffer 和 os cache 中去。</li>
</ul>
<ul>
<li>translog 其实也是先写入 os cache 的，默认每隔 5 秒刷一次到磁盘中去，所以默认情况下，可能有 5 秒的数据会仅仅停留在 buffer 或者 translog 文件的 os cache 中，如果此时机器挂了，会丢失 5 秒钟的数据。但是这样性能比较好，最多丢 5 秒的数据。也可以将 translog 设置成每次写操作必须是直接 fsync 到磁盘，但是性能会差很多。</li>
</ul>
<p>实际上你在这里，如果面试官没有问你 es 丢数据的问题，你可以在这里给面试官炫一把，你说，其实 es 第一是准实时的，数据写入 1 秒后可以搜索到；可能会丢失数据的。有 5 秒的数据，停留在 buffer、translog os cache、segment file os cache 中，而不在磁盘上，此时如果宕机，会导致 5 秒的数据丢失。</p>
<p>总结一下，数据先写入内存 buffer，然后每隔 1s，将数据 refresh 到 os cache，到了 os cache 数据就能被搜索到（所以我们才说 es 从写入到能被搜索到，中间有 1s 的延迟）。每隔 5s，将数据写入 translog 文件（这样如果机器宕机，内存数据全没，最多会有 5s 的数据丢失），translog 大到一定程度，或者默认每隔 30mins，会触发 commit 操作，将缓冲区的数据都 flush 到 segment file 磁盘文件中。</p>
<h2 id="Elasticsearch-在部署时，对-Linux-的设置有哪些优化方法？"><a href="#Elasticsearch-在部署时，对-Linux-的设置有哪些优化方法？" class="headerlink" title="Elasticsearch 在部署时，对 Linux 的设置有哪些优化方法？"></a>Elasticsearch 在部署时，对 Linux 的设置有哪些优化方法？</h2><ul>
<li><p>64 GB 内存的机器是非常理想的， 但是 32 GB 和 16 GB 机器也是很常见的。少于 8 GB 会适得其反。</p>
</li>
<li><p>如果你要在更快的 CPUs 和更多的核心之间选择，选择更多的核心更好。多个内核提供的额外并发远胜过稍微快一点点的时钟频率。</p>
</li>
<li><p>如果你负担得起 SSD，它将远远超出任何旋转介质。 基于 SSD 的节点，查询和索引性能都有提升。如果你负担得起，SSD 是一个好的选择。</p>
</li>
<li><p> 即使数据中心们近在咫尺，也要避免集群跨越多个数据中心。绝对要避免集群跨越大的地理距离。</p>
</li>
</ul>
<ul>
<li>请确保运行你应用程序的 JVM 和服务器的 JVM 是完全一样的。 在Elasticsearch 的几个地方，使用 Java 的本地序列化。</li>
</ul>
<ul>
<li>通过设置 gateway.recover_after_nodes、gateway.expected_nodes、gateway.recover_after_time 可以在集群重启的时候避免过多的分片交换，这可能会让数据恢复从数个小时缩短为几秒钟。</li>
</ul>
<ul>
<li>Elasticsearch 默认被配置为使用单播发现，以防止节点无意中加入集群。只有在同一台机器上运行的节点才会自动组成集群。最好使用单播代替组播。</li>
</ul>
<ul>
<li>不要随意修改垃圾回收器（CMS）和各个线程池的大小。</li>
</ul>
<ul>
<li>把你的内存的（少于）一半给 Lucene（但不要超过 32 GB！），通过ES_HEAP_SIZE 环境变量设置。</li>
</ul>
<ul>
<li>内存交换到磁盘对服务器性能来说是致命的。如果内存交换到磁盘上，一个100 微秒的操作可能变成 10 毫秒。 再想想那么多 10 微秒的操作时延累加起来。 不难看出 swapping 对于性能是多么可怕。</li>
</ul>
<ul>
<li>Lucene 使用了大量 的文件。同时，Elasticsearch 在节点和 HTTP 客户端之间进行通信也使用了大量的套接字。 所有这一切都需要足够的文件描述符。你应该增加你的文件描述符，设置一个很大的值，如 64,000。</li>
</ul>
<h2 id="在并发情况下，Elasticsearch-如果保证读写一致"><a href="#在并发情况下，Elasticsearch-如果保证读写一致" class="headerlink" title="在并发情况下，Elasticsearch 如果保证读写一致"></a>在并发情况下，Elasticsearch 如果保证读写一致</h2><ul>
<li>可以通过版本号使用乐观并发控制，以确保新版本不会被旧版本覆盖，由应用层来处理具体的冲突</li>
</ul>
<ul>
<li><p>另外对于写操作，一致性级别支持 quorum/one/all，默认为 quorum，即只有当大多数分片可用时才允许写操作。但即使大多数可用，也可能存在因为网络等原因导致写入副本失败，这样该副本被认为故障，分片将会在一个不同的节点上重建。</p>
</li>
<li><p>对于读操作，可以设置 replication 为 sync(默认)，这使得操作在主分片和副本分片都完成后才会返回；如果设置 replication 为 async 时，也可以通过设置搜索请求参数_preference 为 primary 来查询主分片，确保文档是最新版本。</p>
</li>
</ul>
<h3 id="从动态索引上优化"><a href="#从动态索引上优化" class="headerlink" title="从动态索引上优化"></a>从动态索引上优化</h3><p>基于模板+时间+rollover api 滚动创建索引，举例：设计阶段定义：blog 索</p>
<p>引的模板格式为：blog_index_时间戳的形式，每天递增数据。</p>
<p>这样做的好处：不至于数据量激增导致单个索引数据量非常大，接近于上线 2 的</p>
<p>32 次幂-1，索引存储达到了 TB+甚至更大。</p>
<p>一旦单个索引很大，存储等各种风险也随之而来，所以要提前考虑+及早避免。</p>
<h3 id="从存储层面优化"><a href="#从存储层面优化" class="headerlink" title="从存储层面优化"></a>从存储层面优化</h3><p>冷热数据分离存储，热数据（比如最近 3 天或者一周的数据），其余为冷数据。</p>
<p>对于冷数据不会再写入新数据，可以考虑定期 force_merge 加 shrink 压缩操作，</p>
<p>节省存储空间和检索效率。</p>
<h3 id="从部署层面优化"><a href="#从部署层面优化" class="headerlink" title="从部署层面优化"></a>从部署层面优化</h3><p>一旦之前没有规划，这里就属于应急策略。</p>
<p>结合 ES 自身的支持动态扩展的特点，动态新增机器的方式可以缓解集群压力，注</p>
<p>意：如果之前主节点等规划合理，不需要重启集群也能完成动态新增的。</p>
<h2 id="Elasticsearch-集群配置"><a href="#Elasticsearch-集群配置" class="headerlink" title="Elasticsearch 集群配置"></a>Elasticsearch 集群配置</h2><p>es 生产集群我们部署了 5 台机器，每台机器是 6 核 64G 的，集群总内存是 320G。<br>我们 es 集群的日增量数据大概是 2000 万条，每天日增量数据大概是 500MB，每月增量数据大概是 6 亿，15G。目前系统已经运行了几个月，现在 es 集群里数据总量大概是 100G 左右。<br>目前线上有 5 个索引（这个结合你们自己业务来，看看自己有哪些数据可以放 es 的），每个索引的数据量大概是 20G，所以这个数据量之内，我们每个索引分配的是 8 个 shard，比默认的 5 个 shard 多了 3 个 shard。</p>

    </div>

    
    
    

    <footer class="post-footer">

        

          <div class="post-nav">
            <div class="post-nav-item">
                <a href="/2023/11/21/%E5%88%86%E5%B8%83%E5%BC%8F%E6%B6%88%E6%81%AF%E5%A4%84%E7%90%86%E6%9C%BA%E5%88%B6-kafka/" rel="prev" title="">
                  <i class="fa fa-chevron-left"></i> 
                </a>
            </div>
            <div class="post-nav-item">
                <a href="/2023/11/21/%E5%88%86%E5%B8%83%E5%BC%8F%E7%BC%93%E5%AD%98%E6%8A%80%E6%9C%AF-redis/" rel="next" title="">
                   <i class="fa fa-chevron-right"></i>
                </a>
            </div>
          </div>
    </footer>
  </article>
</div>






</div>
  </main>

  <footer class="footer">
    <div class="footer-inner">


<div class="copyright">
  &copy; 
  <span itemprop="copyrightYear">2023</span>
  <span class="with-love">
    <i class="fa fa-heart"></i>
  </span>
  <span class="author" itemprop="copyrightHolder">tomstand</span>
</div>
  <div class="powered-by">Powered by <a href="https://hexo.io/" rel="noopener" target="_blank">Hexo</a> & <a href="https://theme-next.js.org/muse/" rel="noopener" target="_blank">NexT.Muse</a>
  </div>

    </div>
  </footer>

  
  <script src="https://cdnjs.cloudflare.com/ajax/libs/animejs/3.2.1/anime.min.js" integrity="sha256-XL2inqUJaslATFnHdJOi9GfQ60on8Wx1C2H8DYiN1xY=" crossorigin="anonymous"></script>
<script src="/js/comments.js"></script><script src="/js/utils.js"></script><script src="/js/motion.js"></script><script src="/js/schemes/muse.js"></script><script src="/js/next-boot.js"></script>

  





  





</body>
</html>
